\documentclass{scrreprt}
\usepackage{xeCJK}
\pagenumbering{gobble}
\usepackage{listings}
\usepackage{underscore}
\usepackage{graphicx}
\usepackage{float}
\usepackage{multirow}
\usepackage{minted}
\usepackage{subcaption}
\usepackage{caption}
\usepackage[bookmarks=true]{hyperref}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\setmonofont{DejaVu Sans Mono}
\renewcommand{\figurename}{图}
\renewcommand{\tablename}{表}
\renewcommand{\listingscaption}{代码}
\newenvironment{code}{\captionsetup{type=listing}}{}
\setminted[python]{
	frame=single,
	framesep=2mm,
	breaklines,
	breakanywhere,
	baselinestretch=1.2,
	fontsize=\footnotesize,
}
%\setminted[html]{
%	frame=single,
%	framesep=2mm,
%	breaklines,
%	breakanywhere,
%	baselinestretch=1.2,
%	fontsize=\footnotesize,
%}


\hypersetup{
    bookmarks=false,    % show bookmarks bar?
    pdftitle={详细设计文档},    % title
    pdfauthor={张权 何朋蒸},                     % author
    pdfsubject={详细设计},                        % subject of the document
    pdfkeywords={详细 底层 设计}, % list of keywords
    colorlinks=true,       % false: boxed links; true: colored links
    linkcolor=blue,       % color of internal links
    citecolor=black,       % color of links to bibliography
    filecolor=black,        % color of file links
    urlcolor=purple,        % color of external links
    linktoc=page            % only page is linked
}%
\def\myversion{1.0 }
\date{}
%\title{%

%}
\usepackage{hyperref}
\begin{document}

\begin{flushright}
    \rule{16cm}{5pt}\vskip1cm
    \begin{bfseries}
        \Huge{DETAILED DESIGN\\DOCUMENT}\\
        \vspace{1.9cm}
        for\\
        \vspace{1.9cm}
        Course Registration System\\
        \vspace{1.9cm}
        \LARGE{Version \myversion approved}\\
        \vspace{1.9cm}
        Prepared by 张权\quad 何朋蒸\\
        \vspace{1.9cm}
        计算机科学与技术学院23班\\
        \vspace{1.9cm}
        \today\\
    \end{bfseries}
\end{flushright}

\tableofcontents


\chapter*{Revision History}

\begin{center}
	\begin{tabular}{|c|c|c|}
		\hline
		Revision & Date & Changes\\
		\hline
		Revision1 & May 27, 2020 & \\
		\hline
	\end{tabular}
\end{center}
\cleardoublepage% ensures that the page numbering will change on a recto page
\pagenumbering{arabic}


% -----------------------------------------------------------
% 引言
% -----------------------------------------------------------
\chapter{引言}

\section{背景}    % 介绍系统概况，阐述项目承担者、用户与其他系统或机构的关系和联系
作为威利学院信息系统的负责人，我们的任务是开发一个新的学生注册系统。 学院希望有一个新的客户端服务器系统来取代现有的围绕主机技术开发的旧系统。新系统将能够允许学生选课，并通过接入校园局域网的个人计算机查看成绩单。教授将能够访问该系统选择教授课程以及记录成绩。
\section{条件与限制}    % 介绍详细设计所处的技术条件、经济条件、时间因素等及其对详细设计的影响；介绍各种限定和限制条件

\begin{enumerate}
	\item 功能性
	
	多个用户必须能够同时执行他们的工作。
	如果一门课程在学生制定包括课程在内的时间表时已满，则必须通知学生。
	\item 可用性
	
	用户界面应符合Windows 10 $\&$ Ubuntu Desktop 18.04等操作系统中的Google Chrome和Mozilla Firefox浏览器。
	\item 可靠性
	
	系统应每周7天，每天24小时可用，停机时间不超过10\%。
	\item 效率
	
	该系统应在任何特定时间支持多达2000个同时使用中央数据库的用户，并在任何时间支持多达500个同时使用本地服务器的用户。
	系统应提供对遗留课程目录数据库的访问，延迟不超过10秒。
	注：基于风险的原型发现，如果没有对中间层处理能力的一些创造性使用，遗留课程目录数据库就无法满足我们的性能需求，系统必须能在2分钟内完成80\%的所有事务。
	\item 可支持性
	
	无。
	\item  安全
	
	该系统必须防止学生改变他们自己以外的任何时间表，以及教授修改为其他教授指定的课程。
	只有教授才能为学生输入成绩。
	只允许管理员更改任何学生信息。
	
\end{enumerate}





\section{定义}    % 对各种专业术语、词条、符号统一定义，对详细设计应完成的目标、思想或方法作严格限定
\paragraph{课程}
大学提供的一门课。
\paragraph{课程提供}
一个特定学期的课程的具体交付，你可以在学期中同时开展相同的课程。不限制每周的天数和次数。
\paragraph{课程目录}
大学提供的所有课程的目录
\paragraph{全体教师}
大学的所有授课老师。
\paragraph{财务系统}
用于处理计费信息的系统。
\paragraph{分数}
对特定学生进行特定课程的评分。
\paragraph{教授}
在大学任教的人。
\paragraph{成绩单}
一个学生在某一学期所修所有课程的所有成绩。
\paragraph{名册}
所有参加特定课程的学生。
\paragraph{学生}
在大学上课的人。
\paragraph{时间表}
学生选择的本学期的课程。
\paragraph{成绩单}
所有课程的历史成绩，上报财务系统并返还学生账单。

\section{背景资料}    % 列举详细设计中所援引的各种标准、规范、技术说明、控制框架文件等
由于资金的减少，学院不能取代整个系统。学院将保留现有的课程目录数据库，所有课程信息都被维护。此数据库是运行在DECVAX上的Ingres关系数据库。幸运的是，学院投资了一个开放的SQL接口，允许从学院的Unix服务器访问这个数据库。遗留系统的性能相当差，因此新系统必须确保能够高校地访问遗留系统上的数据。系统将从遗留数据库访问课程信息，但不会更新数据。管理部门将继续通过另一个系统维护课程信息。

在每个学期开始时，学生可以获取一个课程目录，其中包含一个学期的可选课程清单。将包括关于每门课程的信息，如授课老师、院系和先修课程，以帮助学生做出正确的决定。

新系统将允许学生为下学期选择四门课程。 此外，每个学生将选出两个备选课程，以防学生不能被分配到首要选择。 一个课程最多有10名学生上课，最少有3名学生。选课人数不到3人的课程将被取消。对于每个学期，有一段时间学生可以选课。 学生必须能够在此期间访问系统以添加或删除课程。 一旦学生的选课过程完成，注册系统将信息发送到计费系统，以便学生可以为学期计费。 如果一门课程在实际注册过程中填写，则在提交处理时间表之前，必须通知学生更改。

学期末，学生将能够通过系统查看电子成绩单.. 由于学生成绩是敏感信息，系统必须采取额外的安全措施，以防止未经授权的访问。

教授必须能够访问在线系统，以指示他们将教授哪些课程。 他们还需要看看哪些学生报名参加了他们的课程。 此外，教授将能够记录每个班级学生的成绩。




% -----------------------------------------------------------
% 模块设计
% -----------------------------------------------------------
\chapter{模块设计}\label{ch:moduledesign}
模块设计部分明确了模块的划分，模块的功能以及模块之间的联系。
\section{模块划分依据}    % 阐述模块划分的科学依据，对各模块功能作概括性介绍
基于本系统属于web应用，我们划分模块的依据是\href{https://en.wikipedia.org/wiki/Model-view-controller}{Model–view–controller(MVC)}设计模式，MVC模式将应用分为三大模块：Model，View以及Controller。这样做有助于模块化应用以及代码复用。图\ref{fig:mvc}对MVC模式做了简要的说明\footnote{参考\href{https://alysivji.github.io/flask-part2-building-a-flask-web-application.html}{Building a Flask Web Application (Flask Part 2)}和\href{https://realpython.com/the-model-view-controller-mvc-paradigm-summarized-with-legos/}{Model-View-Controller (MVC) Explained – With Legos}两篇博客}。

\begin{figure}[htbp]
	\centering
	\includegraphics[scale=0.8]{figures/mvc.png}
	\caption{MVC模式的简单介绍实际上可细分为routes,model,view和controller四个模块。在Flask框架中，每一个route与一个controller联系在一起，即一个route绑定一个view function，路由确定页面的URL，而view funciton处理这个页面的操作。Models负责从数据库中提取数据，对其进行操作和整理，将其传递到某一个页面。Views即为用户看到的界面，在Flask框架的设计中，这部分是由HTML和Jinja2提供基本的支持，另外需要CSS,Bootstrap和Javascript等工具的支持。}
	\label{fig:mvc}
\end{figure}

\section{模块结构与功能描述}    % 给出模块关系结构，并对模块间接口(入口、出口参数)以及模块功能作详细介绍
\subsection{Routes}
代码\ref{code:routedemo}展示了Flask框架中route的基本模式，并说明了其与views中的模板的接口模式。
\begin{code}
	\inputminted[linenos]{python}{code/routedemo.py}
	\caption{路由示例.代码第一行定义路由，设置URL为'/'，表示根路径。第2-7行为与该路由绑定的view function，其中第7行return 语句使用render\_template语句，将参数greeting传递到html模板中，将其展示给用户。路由可以接收参数，可以使用redirect函数重定向到另一个URL，可以在view function前加入decorator，例如$@login\_reqired$等。}
	\label{code:routedemo}
\end{code}
\subsection{Controller}
在代码\ref{code:routedemo}中第2-7行的view function即为controller的示例，其可以接受参数并从数据库中提取数据加以整理，最后传递到views中的模板。
\subsection{Models}
代码\ref{code:modeldemo}和\ref{code:modeldemowithcontroller}展示了在Flask框架中models模块的定义和使用实例。
\begin{code}
	\inputminted[linenos]{python}{code/inputboxmodel.py}
	\caption{定义消息箱模型，其为关系数据库中的一个表(关系)}
	\label{code:modeldemo}
\end{code}
\begin{code}
	\inputminted[linenos]{python}{code/modeldemowithcontroller.py}
	\caption{在view function中提取数据库中的数据，并进行操作}
	\label{code:modeldemowithcontroller}
\end{code}

\subsection{Views}
Views模块存储HTML界面，用于展示给用户。在Flask中除了可用CSS和Bootstrap对其进行装饰之外，还可以用Jinja2对页面内容和数据进行控制。代码\ref{code:viewdemo}展示了一个具体的例子，其中包含了模板继承，控制流，布局组件等元素。
\begin{code}
	\inputminted[linenos,breaklines]{html}{code/viewdemo.html}
	\caption{模板实例.Jinja2提供了自己的页面格局控制，在其中可以使用python语法实现for loop和if else控制流。此外，模板可以进行继承，Flask-Wtf提供了表单支持。}
	\label{code:viewdemo}
\end{code}

% -----------------------------------------------------------
% 代码设计
% -----------------------------------------------------------
\chapter{代码设计}\label{ch:codedesign}    % 各类代码名称、功能、相应的编码表、使用范围、使用要求及对代码的评价
\section{后端代码}
后端代码用Python编写，实现了MVC中的models和controller(包括routes)模块。
\subsection{数据库模块}
\href{https://www.sqlalchemy.org/}{SQLALCHEMY}提供了通过python语言操作数据库的接口，从而数据库模块可以使用python代码进行编写。其通过\href{https://en.wikipedia.org/wiki/Object-relational_mapping}{Object-relational mapping}将模型类的对象映射为关系，并将其query接口转换为sql语句，从而实现数据库的建立与操作。代码\ref{code:modeldemo}即为一个示例，模型类继承了db.Model，从而使其能够定义数据库关系中属性的类型，并能够被映射为数据库对象。另外，还可以在模型类中定义property和辅助函数协助数据库的工作，代码\ref{code:professormodel}提供了示例。
\subsection{表单}
表单的编写可用html原生的form标签，也可用Flask提供的表单类。在本项目中绝大部分表单的编写采用Flask的表单类，在前端用flask-bootstrap提供的WTForms支持将其渲染成html表单，在必要的时候使用html原生表单以实现特定功能。当用户填写完成表单时，用户点击相应的提交按钮，后端view function可以根据表单对象的validate\_on\_submit()函数验证其是否提交并且表单每项的数据是否满足相应的约束。代码\ref{code:formdemo}和\ref{code:getformdatademo}展示了其使用方法和作用。

\begin{code}
	\inputminted[linenos]{python}{code/formdemo.py}
	\caption{Flask表单类的示例.这是一个用于用户登录的表单类，某些表单项需要对数据进行约束，可通过validators等参数进行设置}
	\label{code:formdemo}
\end{code}
\begin{code}
	\inputminted[linenos]{python}{code/getformdatademo.py}
	\caption{获取表单数据示例.当form.validate\_on\_submit()函数返回True时，表单被提交，后端对其数据进行处理}
	\label{code:getformdatademo}
\end{code}
\subsection{后端主体}
后端主体一部分是对应用本身的配置，包括对应用运行参数的配置，对数据库的配置等；另一部分是诸如代码\ref{code:modeldemowithcontroller}这样的route配置和相应的view function的编写，这一部分是程序功能的主要体现。代码\ref{code:createapp}展示了对应用本身的一部分配置操作。
\begin{code}
	\inputminted{python}{code/createapp.py}
	\caption{对应用对象本身的一部分配置操作.例如，将应用与数据库等对象绑定，将蓝图注册到应用中等.}
	\label{code:createapp}
\end{code}
\section{前端代码}
前端代码主要由每个页面的html模板、对其进行装饰的css文件以及用于完成特定页面功能的脚本文件构成。
\subsection{模板代码}
模板代码即为页面的html模板，内部嵌入Jinja2和boootstrap等元素。其作用是为用户提供良好的交互接口和简洁自然的界面视图。代码\ref{code:viewdemo}是一个具体的示例。
\subsection{静态文件}
静态文件是由一些CSS文件和Javascript脚本文件组成，用于对html模板进行装饰和功能上的补充。这部分代码可以内嵌在html代码中，但是将其分离出来可使代码更加模块化，也实现了\textbf{代码的复用}。
% -----------------------------------------------------------
% 数据库设计
% -----------------------------------------------------------
\chapter{数据库设计}

\section{数据库总体结构}
数据库中采用了以下实体对象:
\begin{itemize}
	\item Course：课程
	\item Student：学生
	\item Professor：教授
	\item Registrar：管理员
	\item Section：课程段
	\item Bill：账单
	\item Inputbox：消息箱
\end{itemize}
数据库中采用了以下关系对象:
\begin{itemize}
	\item Takes：学生选课情况
	\item Teaches：教授教课情况
	\item Prerequisite：先修课程情况	
\end{itemize}

\section{数据库逻辑设计}    % 包括命名原则、数据层的组织结构、投影方式和坐标记录格式、数据库结构(建库)等
如图\ref{fig:databaseer}所示
\begin{figure}[H]
	\centering
	\includegraphics[scale=1]{figures/databaseer.png}
	\caption{数据库逻辑设计.其中每个table里带下划线的属性为该table的primary key.}
	\label{fig:databaseer}
\end{figure}
\section{数据库物理设计}    % 包括物理存储方式(目前多采用客户一服务器体系)、海量存储的物理分配、容量设计及增容措施等
\subsection{教授模板类}
如代码\ref{code:professormodel}
\begin{code}
	\inputminted{python}{code/professormodel.py}
	\caption{教授模板类}
	\label{code:professormodel}
\end{code}
\subsection{学生模板类}
如代码\ref{code:studentmodel}
\begin{code}
	\inputminted{python}{code/studentmodel.py}
	\caption{学生模板类}
	\label{code:studentmodel}
\end{code}
\subsection{管理员模板类}
如代码\ref{code:registrarmodel}
\begin{code}
	\inputminted{python}{code/registrarmodel.py}
	\caption{管理员模板类}
	\label{code:registrarmodel}
\end{code}
\subsection{课程模板类}
如代码\ref{code:coursemodel}
\begin{code}
	\inputminted{python}{code/coursemodel.py}
	\caption{课程模板类}
	\label{code:coursemodel}
\end{code}
\subsection{账单模板类}
如代码\ref{code:billmodel}
\begin{code}
	\inputminted{python}{code/billmodel.py}
	\caption{账单模板类}
	\label{code:billmodel}
\end{code}
\subsection{先修课程模板类}
如代码\ref{code:prerequisitemodel}
\begin{code}
	\inputminted{python}{code/prerequisitemodel.py}
	\caption{先修课程模板类}
	\label{code:prerequisitemodel}
\end{code}
\subsection{授课模板类}
如代码\ref{code:teachesmodel}
\begin{code}
	\inputminted{python}{code/teachesmodel.py}
	\caption{授课模板类}
	\label{code:teachesmodel}
\end{code}
\subsection{上课模板类}
如代码\ref{code:takesmodel}
\begin{code}
	\inputminted{python}{code/takesmodel.py}
	\caption{上课模板类}
	\label{code:takesmodel}
\end{code}
\subsection{消息箱模板类}
如代码\ref{code:inputboxmodel}
\begin{code}
	\inputminted{python}{code/inputboxmodel.py}
	\caption{消息箱模板类}
	\label{code:inputboxmodel}
\end{code}
\subsection{课程段模板类}
如代码\ref{code:sectionmodel}
\begin{code}
	\inputminted{python}{code/sectionmodel.py}
	\caption{课程段模板类}
	\label{code:sectionmodel}
\end{code}
\section{数据库管理要求}    % 包括对数据库安全性、保密性、完整性、一致性的要求及各种保证措施
\begin{enumerate}
	\item 每周末要按时备份数据库；
	\item 若发现数据库有潜在隐患，要及时排查修复。
\end{enumerate}





% -----------------------------------------------------------
% 用户界面设计
% -----------------------------------------------------------
\chapter{用户界面设计}\label{ch:viewdesign}
用户界面设计的目的是，为用户提供良好的交互接口和美观简洁的页面布局。并且在保证系统安全性的情况下，使用户能够通过接口完整其操作目的。
\section{用户界面设计原则}
图\ref{fig:overallarchitecture}展示了页面的整体结构，并介绍了界面设计的基本原则，其中student,professor和registrar都是一个的模块。
\begin{figure}[H]
	\centering
	\includegraphics[scale=0.5]{figures/overallarchitecture.png}
	\caption{页面的总体结构关系:用户进入系统时处于main.index界面,这个时候是未登录状态，系统为用户提供唯一的接口，即"登录"。用户点击登录按钮后转到auth.login页面，在这个页面，用户填写登录表单，提交后，后端处理登录信息，并根据用户名自动确认用户身份。若身份验证成功，页面转到相应身份的home页面。若验证失败，则根据失败原因提示错误信息，页面停留在auth.login，并要求用户重新填写表单，再次登录。当用户验证成功转到自己的主页之后，用户有唯一的接口回到main.index，即"退出登录"，而其他所有接口都不会使用户离开其身份所属的蓝图，保证了系统安全性。}
	\label{fig:overallarchitecture}
\end{figure}
\section{交互式菜单设计}    % 设计用于交互式操作的菜单原型
交互式菜单即用户接口，要求直观简洁，并且有相应的提示信息。在本次项目中，绝大部分的接口为链接或带按钮形式。要求按钮和链接名需要表明本接口的作用和目的。以下为设计要点：
\begin{enumerate}
	\item 所有页面均提供导航栏，导航栏提供用户权限范围内的功能入口接口，便于用户随时进入到想要使用的功能的主界面。
	
	\item 若某一项操作由于某种原因未能实现，则需要将相关的错误信息用跳出信息的方式通知用户，并且尽可能给出指示信息指导用户正确操作。若操作成功，也应弹出通知消息给予用户反馈。这里采用Flask的flash()函数将消息弹出，并显示在导航栏的下方。
	
	\item 当用户正在执行某些不可挽回的操作，例如学生退选课程，老师退选课程，管理员删除学生、老师以及取消课程时，系统将用弹窗警告的方式向用户进行警告，并询问用户是否继续操作。用户此时可以点击取消以取消操作或点击确定以继续操作。
	
	\item 当用户填写表单时，若表项格式不正确或内容不合理，将立即提醒用户并指示正确的格式或内容，让用户再次填写。对于有内容范围的表单项，采用单选下拉列表的方式，使用户直接在可选项目中选择，从而避免错误输入和不合适的输入。
\end{enumerate}

\subsection{学生页面}
图\ref{fig:studentview}、图\ref{fig:professorview}和图\ref{fig:registrarview}展示了学生、老师和管理员试图的页面联系和接口设计。
\begin{figure}[H]
	\centering
	\includegraphics[scale=0.5]{figures/studentview.png}
	\caption{学生蓝图的接口设计.其中学生主页、选课页面、消息、查看成绩单和账单系统均在导航栏；导航栏还包括退出登录接口，图中未画出。}
	\label{fig:studentview}
\end{figure}
\subsection{教师页面}
\begin{figure}[H]
	\centering
	\includegraphics[scale=0.5]{figures/professorview.png}
	\caption{教师蓝图的接口设计.其中选课、消息和录入成绩接口均在导航栏导航栏还包括退出登录接口，图中未画出。；}
	\label{fig:professorview}
\end{figure}
\subsection{管理员页面}
\begin{figure}[H]
	\centering
	\includegraphics[scale=0.5]{figures/registrarview.png}
	\caption{学生蓝图的接口设计.其中管理学生信息、管理教师信息以及取消课程接口均在导航栏；导航栏还包括退出登录接口，图中未画出。}
	\label{fig:registrarview}
\end{figure}
\section{布局设计}    % 平衡各种界面，在符合用户要求和习惯的前提下，参照美学原理、人体工程学原理优化菜单及界面布局
所有界面顶部均为导航栏，导航栏给出了用户在当前状态和身份下可以使用的接口，方便用户随时进入各项功能的主界面。如果有弹出消息则显示在导航栏的下方。在此之下为页面主题内容，内容字体即内容块大小随用户浏览器窗口大小而变，尽可能在屏幕重要区域显示。显示的列表项目保持一致的风格，项目之间留有足够的间隙，为用户提供清晰的界面。



% -----------------------------------------------------------
% 输入／输出设计
% -----------------------------------------------------------
\chapter{输入／输出设计}

\section{输入设计}    % 输入项目、输入设备、功能要求、输入检验、输入质量控制
用户的输入分为两种：HTTP请求和表单填写提交。
\subsection{HTTP请求}
用户在所处界面点击相关功能接口，浏览器向服务器发起HTTP请求，并传递相应的参数信息到后端，交给服务器处理。要求系统提供给用户的接口能够准确传达用户请求的含义和所需的参数。
\subsection{表单的填写和提交}
系统在相关界面提供必要的表单供用户填写。下面列举出了所有的表单设计及其相关的约束：
\begin{enumerate}
	\item \textbf{用户登录表单}
	\begin{table}[H]
		\centering
		\resizebox{\columnwidth}{!}{
		\begin{tabular}{|c|c|c|c|c|}
			\hline
			表项名          & 作用                & 数据类型          & 验证要求 & 提示信息   \\ \hline
			id           & 用于确认用户身份的唯一标识     & IntegerField  & 必填   & "用户名"  \\ \hline
			password     & 用户密码              & PasswordField & 必填   & "密码"   \\ \hline
			remember\_me & 用于标识是否需要浏览器记住登录状态 & BooleanField  & 可选   & "保持登录" \\ \hline
			submit       & 确认提交              & SubitField    & 点击   & "登录"   \\ \hline
		\end{tabular}}
	\caption{LoginForm.用于用户登录}
	\end{table}
	\item \textbf{学生充值表单}
	\begin{table}[H]
		\centering
		\resizebox{\columnwidth}{!}{
		\begin{tabular}{|c|c|c|c|c|}
			\hline
			表项名    & 作用         & 数据类型       & 验证要求              & 提示信息 \\ \hline
			amount & 填写用户要充值的金额 & FloatField & 必填，且符合货币的格式，要求大于零 & "金额" \\ \hline
			submit & 确认提交       & SubitField & 点击                & "确认充值" \\ \hline
		\end{tabular}}
	\caption{DepostForm.用于学生充值}
	\end{table}
	\item \textbf{老师提交成绩表单}
	\begin{table}[H]
		\centering
		\resizebox{\columnwidth}{!}{
		\begin{tabular}{|c|c|c|c|c|}
			\hline
			表项名    & 作用     & 数据类型        & 验证要求            & 提示信息       \\ \hline
			grade  & 填写学生成绩 & StringField & 必填，且满足系统要求的成绩格式 & "成绩"       \\ \hline
			submit & 确认提交   & SubitField  & 点击              & "确认提交学生成绩" \\ \hline
		\end{tabular}}
	\caption{GradeForm.用于教师提交学生成绩}
	\end{table}
	\item \textbf{管理员添加学生表单}
	\begin{table}[H]
		\centering
		\resizebox{\columnwidth}{!}{
		\begin{tabular}{|c|c|c|c|c|c|}
			\hline
			表项名                      & 作用     & 数据类型          & 验证要求                & 提示信息     & 备注                                                         \\ \hline
			student\_id              & 填写学生学号 & IntgeterField & \multirow{9}{*}{必填} & "学号"     & \multirow{3}{*}{}                                          \\ \cline{1-3} \cline{5-5}
			password                 & 填写密码   & StringField   &                     & "初始密码"   &                                                            \\ \cline{1-3} \cline{5-5}
			student\_name            & 学生姓名   & StringField   &                     & "姓名"     &                                                            \\ \cline{1-3} \cline{5-6} 
			date\_of\_birth          & 出生日期   & StringField   &                     & "出生日期"   & 将其转换为Date类型                                                \\ \cline{1-3} \cline{5-6} 
			social\_security\_number & 身份证号码  & StringField   &                     & "身份证号码"  &                                                            \\ \cline{1-3} \cline{5-6} 
			status                   & 学历     & SelectField   &                     & "学历"     & \begin{tabular}[c]{@{}c@{}}可选项设置为\\ 系统允许的学历选项\end{tabular} \\ \cline{1-3} \cline{5-6} 
			graduation\_date         & 毕业日期   & StringField   &                     & "毕业日期"   & 将其转换为Date类型                                                \\ \cline{1-3} \cline{5-6} 
			department               & 学院     & SelectField   &                     & "学院"     & \begin{tabular}[c]{@{}c@{}}可选项设置为\\ 系统允许的学院选项\end{tabular} \\ \cline{1-3} \cline{5-6} 
			balance                  & 初始余额   & FloatField    &                     & "初始余额"   & \multirow{2}{*}{}                                          \\ \cline{1-5}
			submit                   & 确认提交   & SubmitField   & 点击                  & "确认添加学生" &                                                            \\ \hline
		\end{tabular}}
	\caption{NewStudentForm.用于管理员添加学生}
	\end{table}
	\item \textbf{管理员修改学生信息表单}
	\begin{table}[H]
		\centering
		\resizebox{\columnwidth}{!}{
		\begin{tabular}{|c|c|c|c|c|c|}
			\hline
			表项名                      & 作用     & 数据类型          & 验证要求                & 提示信息     & 备注              \\ \hline
			student\_id              & 填写学生学号 & IntgeterField & 必填                  & "学号"     &                 \\ \hline
			password                 & 填写密码   & StringField   & \multirow{7}{*}{可选} & "初始密码"     &                 \\ \cline{1-3} \cline{5-6} 
			student\_name            & 学生姓名   & StringField   &                     & "姓名"     &                 \\ \cline{1-3} \cline{5-6} 
			date\_of\_birth          & 出生日期   & StringField   &                     & "出生日期"   & 将其转换为Date类型     \\ \cline{1-3} \cline{5-6} 
			social\_security\_number & 身份证号码  & StringField   &                     & "身份证号码"  &                 \\ \cline{1-3} \cline{5-6} 
			status                   & 学历     & SelectField   &                     & "学历"     & 可选项设置为系统允许的学历选项 \\ \cline{1-3} \cline{5-6} 
			graduation\_date         & 毕业日期   & StringField   &                     & "毕业日期"   & 将其转换为Date类型     \\ \cline{1-3} \cline{5-6} 
			department               & 学院     & SelectField   &                     & "学院"     & 可选项设置为系统允许的学院选项 \\ \hline
			submit                   & 确认提交   & SubmitField   & 点击                  & "确认更新学生信息" &                 \\ \hline
		\end{tabular}}
	\caption{UpdateStudentForm.用于管理员修改学生信息}
	\end{table}
	\item \textbf{管理员查询学生表单}
	\begin{table}[H]
		\centering
		\begin{tabular}{|c|c|c|c|c|}
			\hline
			表项名         & 作用     & 数据类型          & 验证要求 & 提示信息 \\ \hline
			student\_id & 填写学生学号 & IntgeterField & 必填   & "学号" \\ \hline
			submit      & 确认提交   & SubmitField   & 点击   & "确定" \\ \hline
		\end{tabular}
	\caption{StudentForm.用于查询学生，查询后可用于显示学生信息或者删除学生}
	\end{table}
	\item \textbf{管理员添加教师表单}
	\begin{table}[H]
		\centering
		\resizebox{\columnwidth}{!}{
		\begin{tabular}{|c|c|c|c|c|c|}
			\hline
			表项名                      & 作用     & 数据类型          & 验证要求 & 提示信息     & 备注              \\ \hline
			professor\_id            & 填写教师工号 & IntgeterField & 必填   & "教师工号"   &                 \\ \hline
			password                 & 填写密码   & StringField   & 必填   & "初始密码"   &                 \\ \hline
			student\_name            & 教师姓名   & StringField   & 必填   & "姓名"     &                 \\ \hline
			date\_of\_birth          & 出生日期   & StringField   & 必填   & "出生日期"   & 将其转换为Date类型     \\ \hline
			social\_security\_number & 身份证号码  & StringField   & 必填   & "身份证号码"  &                 \\ \hline
			status                   & 职称     & SelectField   & 必填   & "职称"     & 可选项设置为系统允许的职称选项 \\ \hline
			department               & 学院     & SelectField   & 必填   & "学院"     & 可选项设置为系统允许的学院选项 \\ \hline
			submit                   & 确认提交   & SubmitField   & 点击   & "确认添加教师" &                 \\ \hline
		\end{tabular}}
	\caption{NewProfessorForm.用于管理员添加教师表单}
	\end{table}
	\item \textbf{管理员更新教师信息表单}
	\begin{table}[H]
		\centering
		\resizebox{\columnwidth}{!}{
		\begin{tabular}{|c|c|c|c|c|c|}
			\hline
			表项名                      & 作用     & 数据类型          & 验证要求                & 提示信息       & 备注              \\ \hline
			professor\_id            & 填写教师工号 & IntgeterField & 必填                  & "教师工号"     &                 \\ \hline
			password                 & 填写密码   & StringField   & \multirow{6}{*}{可选} & "初始密码"     &                 \\ \cline{1-3} \cline{5-6} 
			student\_name            & 教师姓名   & StringField   &                     & "姓名"       &                 \\ \cline{1-3} \cline{5-6} 
			date\_of\_birth          & 出生日期   & StringField   &                     & "出生日期"     & 将其转换为Date类型     \\ \cline{1-3} \cline{5-6} 
			social\_security\_number & 身份证号码  & StringField   &                     & "身份证号码"    &                 \\ \cline{1-3} \cline{5-6} 
			status                   & 职称     & SelectField   &                     & "职称"       & 可选项设置为系统允许的职称选项 \\ \cline{1-3} \cline{5-6} 
			department               & 学院     & SelectField   &                     & "学院"       & 可选项设置为系统允许的学院选项 \\ \hline
			submit                   & 确认提交   & SubmitField   & 点击                  & "确认更新教师信息" &                 \\ \hline
		\end{tabular}}
	\caption{UpdateProfessorForm.用于管理员更新教师信息表单}
	\end{table}
	\item \textbf{管理员查询教师表单}
	\begin{table}[H]
		\centering
		\begin{tabular}{|c|c|c|c|c|}
			\hline
			表项名           & 作用     & 数据类型          & 验证要求 & 提示信息   \\ \hline
			professor\_id & 填写教师工号 & IntgeterField & 必填   & "教师工号" \\ \hline
			submit        & 确认提交   & SubmitField   & 点击   & "确定"   \\ \hline
		\end{tabular}
	\caption{ProfessorForm.用于查询教师，查询后可用于查看教师信息或者删除教师}
	\end{table}
\end{enumerate}
\section{输出设计}    % 输出项目、输出设备、功能要求、评价与检验
所有的输出均呈现在相应的html模板中。后端处理用户请求和相关参数之后，将返回的结果传递到相应的模板中，用尽可能美观和简洁的方式呈现给用户。



% -----------------------------------------------------------
% 程序模块设计
% -----------------------------------------------------------
\chapter{程序模块设计}    % 程序模块的算法及其优化措施，逻辑流程的框图，出／入口参数及外部接口标准
将程序模块化设计有利于维护和代码复用，在第\ref{ch:moduledesign}章和第\ref{ch:codedesign}中阐述了程序在功能上的模块划分依据和不同类代码的依据。本章给出实际项目中各部分文件的结构。

下面列出了项目的2层结构树。其中auth,main,student,professor,registrar文件夹(python package)分别是系统的5个蓝图，每个包存储了该蓝图所需的route设置，view function的实现，Flask表单类的实现，以及错误处理；具体地说，每个蓝图对应的包里，$\_\_init\_\_.py$是对该蓝图的定义和配置，forms.py定义了该蓝图需要用到的表单类，errors.py定义了错误类，views.py定义了该蓝图的route和view function的实现。models.py定义了数据库中各种关系类；database\_setup.py是数据库的初始化脚本，其将csvFile文件夹中的初始数据加入到数据库文件data-dev.sqlite中；config.py定义了不同场景下的配置类；$\_\_inin\_\_.py$是定义了应用的初始配置，app.py中创建了应用实例。主目录下的templates文件夹是Flask框架中存放模板文件的位置，除main蓝图之外的蓝图模板均放在templates文件夹的子目录下；static保存静态文件；doc文件夹下保存了项目的可行性分析、需求分析文档，测试计划和测试文档、概要设计和详细设计文档。tests文件夹中对用户类的基本要求做了部分单元测试。requirements.txt文件说明了项目的依赖库。
\begin{code}
	\inputminted{text}{files/level2.txt}
\end{code}
% -----------------------------------------------------------
% 安全性设计
% -----------------------------------------------------------
\chapter{安全性设计}    % 用户权限的划分；数据的安全保护措施：如副本、倒库期限、日志等；数据的完整性检验条件设计
本项目主要的安全性考虑分为数据库安全性和接口的安全性两部分。
\section{数据库的安全性}
\subsection{用户权限的安全性}
代码\ref{code:userdemo}和\ref{code:anonymoususerdemo}展示了普通用户类和匿名用户类的定义。普通用户类是能够正常登录到程序的用户，其继承了db.Model，其实例将存储到数据库中。
\begin{code}
	\inputminted{python}{code/userdemo.py}
	\caption{教师类的部分定义. 教师作为程序的用户身分之一，教师类继承了Flask提供的用户类$UserMixin$，使其具有用户身份的权限；另外，以上代码展示的这部分函数具有验证身份以确定权限的作用。对于学生类和管理员类也有同样的处理。}
	\label{code:userdemo}
\end{code}
\begin{code}
	\inputminted{python}{code/anonymoususerdemo.py}
	\caption{匿名用户类的定义. 匿名用户的作用是作为登录账户前用户的暂时身份，其不能访问需要登陆才能访问的界面；这里匿名用户类继承了Flask提供的$AnonymousUserMixin$类。其不具备其他任何权限。}
	\label{code:anonymoususerdemo}
\end{code}
除此之外，用户登录之后的URLs(路由)都是需要登录到账户猜可能有权限访问的，故在这些路由下面加入了$@login_required$注解，这个注解由Flask框架提供，实际编写程序的时候可以将其覆盖(override)，以达到实际需要。这写设计和考虑在一定程度上确保了身份信息的安全性，以防止没有登录和没有权限的用户进入到那些需要登录才能查看的页面。

\subsection{用户数据的安全性}
用户数据的安全性主要考虑了用户的账户密码信息。在设计上，账户的密码不应明文存储，故数据库中实际存储的并非用户的密码，而是通过Flask提供的generate\_password\_hash(password)函数产生密码的hash值，存储与数据库中。Flask还提供了check\_password\_hash(password\_hash, password)函数用于验证密码是否正确，以实现用户登录。对这两个函数还要求
\begin{enumerate}
	\item 对与同一个用户，当check\_password\_hash(password\_hash, password)函数接受的密码为正确密码时，函数总是返回True；对于错误的密码，函数总是返回False。结果只根据密码正确与否有关，不随其他因素而改变。
	
	\item 对于不同用户，即使用户密码相同，但generate\_password\_hash(password)生成的hash值应不同。如代码\ref{code:hashtest}所示：
	\begin{code}
		\begin{minted}{python}
class UserModelTestCase(unittest.TestCase):
    def test_password_salts_are_random(self):
        u = Student(password='12345678')
        u2 = Student(password='12345678')
        self.assertTrue(u.password_hash != u2.password_hash)
		\end{minted}
		\caption{对密码hash的部分验证}
		\label{code:hashtest}
	\end{code}
\end{enumerate}

\subsection{数据库自身的安全性}
数据库主要的安全性考虑是在不同线程访问数据库的相同数据(包含相同数据的关系)，要保证读写操作的串行化，从而确保数据一致性。更新数据库之后需对数据库及时进行commit()操作，否则数据不会更新到数据库。Flask对数据库的同步操作提供了内部支持，以保证数据的安全。

\section{接口的安全性}
接口的安全性需要保证匿名用户不能访问需要登录才能访问的路由；保证不同身份的用户不会进入到非自己身份能够进入的路由。这需要在给用户提供界面时谨慎处理。具体的接口设计详见第\ref{ch:viewdesign}章。



% -----------------------------------------------------------
% 方案实施与管理
% -----------------------------------------------------------
\chapter{方案实施与管理}    % 用户权限的划分；数据的安全保护措施：如副本、倒库期限、日志等；数据的完整性检验条件设计

\section{方案实施说明}
\begin{enumerate}
	\item 起止时间:5月25日到6月15日
	\item 项目预期成果:
	\begin{enumerate}
		\item 一套完善的课程注册系统
		\item 一套简洁明了的技术文档
	\end{enumerate}
\end{enumerate}

\section{工作任务分解}    % 根据任务性质、工作量大小，按照管理模式做工作任务分解，确保整体工作效率
\begin{enumerate}
	\item 开发计划
	\item 需求分析
	\item 设计文档
	\item 编程实现
	\item 测试计划和测试报告
	\item 工作总结
	\item 程序运行检查
\end{enumerate}
\section{进度安装}
\paragraph{第一周}项目开发计划、可行性分析、需求分析的讨论及相关文档的撰写
\paragraph{第二周}设计文档撰写、数据库设计、前端界面设计、后端编码与调试
\paragraph{第三周}代码集成、测试计划文档撰写、系统功能测试、测试报告文档撰写
系统界面美化以及EV录屏

\section{经费预算与管理}
不需要经费。
\end{document}
